
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import pandas as pd

from fund.strategy.strategy_by_dca import daily_invest
from fund.strategy.strategy_by_drop import strategy_based_on_drop
from fund.strategy.strategy_by_ma import strategy_based_on_moving_average
from util.csv_util import csv_2_df
from util.date_util import *


def p1():

    # fund_code = 580006  # 东吴
    # fund_code = '018993' # 中欧
    fund_code = '000055' # 广发纳斯达克

    # 1. 字体配置（不变）
    plt.rcParams["font.family"] = ["SimHei"]
    plt.rcParams["axes.unicode_minus"] = False  # 解决负号显示问题


    sd = before_n_years_yyyymmdd(8)
    # ed = yesterday_yyyymmdd()
    ed = before_6m_yyyymmdd()

    # 把 sd/ed 转为 datetime 类型（与基金数据索引格式统一）
    sd_dt = pd.to_datetime(sd)
    ed_dt = pd.to_datetime(ed)

    # 2. 读取基金数据 + 关键：按指定时间范围筛选数据
    fund_data = csv_2_df(f"fund/history_data/{fund_code}-daily.csv")

    # 截取 [sd, ed] 区间内的基金数据（核心筛选步骤）
    fund_data_filtered = fund_data[(fund_data.index >= sd_dt) & (fund_data.index <= ed_dt)]

    # 3. 获取策略结果（传入的 sd/ed 是字符串，策略函数内部会转 datetime，无需改）
    result = strategy_based_on_drop(fund_data, 200, start_date=sd, end_date=ed)
    # result = strategy_based_on_moving_average(fund_data, 0, 200, 30, start_date=sd, end_date=ed)
    result2 = daily_invest(fund_data, 200, start_date=sd, end_date=ed)

    # 4. 关键：筛选指定时间范围内的买入记录（避免显示范围外的买入点）
    filtered_buy_records = [
        record for record in result['买入记录']
        if sd_dt <= record['date'] <= ed_dt  # 只保留区间内的买入点
    ]

    # 提取筛选后的买入日期和价格
    buy_dates = [record['date'] for record in filtered_buy_records]
    buy_prices = [record['price'] for record in filtered_buy_records]

    # 5. 创建图表 + 用筛选后的数据绘图
    fig, ax = plt.subplots(figsize=(12, 6))

    # 绘制筛选后的基金净值曲线（不再是整个DataFrame）
    ax.plot(fund_data_filtered.index, fund_data_filtered['单位净值'], label='基金净值', linewidth=2)

    # 绘制筛选后的买入点（不再显示范围外的点）
    if buy_dates:  # 避免无买入点时报错
        ax.scatter(buy_dates, buy_prices, color='red', s=50, alpha=0.7, label='买入点')

    # 6. 收益率信息（不变）
    total_return = result['总收益率'] * 100
    annual_return = result['年化收益率'] * 100
    total_return2 = result2['总收益率'] * 100
    annual_return2 = result2['年化收益率'] * 100

    # 文本框显示收益率
    props = dict(boxstyle='round', facecolor='wheat', alpha=0.5)
    textstr = (f'总收益率: {total_return:.2f}%\n年化收益率: {annual_return:.2f}%\n'
               f'定投总收益率: {total_return2:.2f}%\n定投年化收益率: {annual_return2:.2f}%')
    ax.text(0.95, 0.95, textstr, transform=ax.transAxes, fontsize=12,
            verticalalignment='top', bbox=props, horizontalalignment='right')

    # 7. 图表格式（不变）
    ax.set_title('基金净值与策略买入点', fontsize=16)  # 标题补充时间范围，更清晰
    ax.set_xlabel('日期', fontsize=12)
    ax.set_ylabel('单位净值', fontsize=12)
    ax.grid(True, linestyle='--', alpha=0.7)
    ax.legend()

    # 日期格式优化
    ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d'))
    ax.xaxis.set_major_locator(mdates.MonthLocator(interval=3))  # 每3个月显示一个刻度，避免拥挤
    plt.xticks(rotation=45)

    plt.tight_layout()
    plt.show()


if __name__ == '__main__':
    p1()